<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>数据集处理流水线可视化系统</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  <link rel="stylesheet" href="database-panel-fix.css">
  <link rel="stylesheet" href="layout-fix.css">
  <link rel="stylesheet" href="layout-fix-v2.css">
  <style>
      :root {
          --step-1-color: #4286f4;
          --step-2-color: #ff8c00;
          --step-3-color: #43cea2;
          --step-4-color: #9c27b0;
          --panel-color: #4285F4;
          --card-bg: #ffffff;
          --header-bg: #f8f9fa;
          --table-header-bg: #e9ecef;
          --added-color: #e8f5e9;
          --removed-color: #ffebee;
          --modified-color: #fff3e0;
          --split-color: #e1f5fe;
          --aggregate-color: #f3e5f5;
          --missing-color: #f8f9fa;
          --highlight-color: #e3f2fd;
          --border-color: #e0e0e0;
          --relation-color: #7e57c2;
          --tab-active: #4285F4;
          --tab-inactive: #5f6368;
          --gray-text: #757575;
      }

      * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
          font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      }

      body {
          background: linear-gradient(135deg, #f0f2f5 0%, #e4eaf0 100%);
          color: #333;
          min-height: 100vh;
      }

      .app-container {
          display: flex;
          flex-direction: column;
          min-height: 100vh;
          width: 100%;
          margin: 0;
          background: white;
          overflow: hidden;
      }

      /* 顶部工具条 */
      .toolbar {
          display: flex;
          justify-content: space-between;
          align-items: center;
          background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
          color: white;
          padding: 15px 30px;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
          position: sticky;
          top: 0;
          z-index: 100;
      }

      .toolbar-title {
          display: flex;
          align-items: center;
          font-size: 1.6rem;
          font-weight: 600;
      }

      .toolbar-title i {
          margin-right: 15px;
          font-size: 1.8rem;
          color: var(--step-1-color);
      }

      .toolbar-buttons {
          display: flex;
          gap: 15px;
      }

      .toolbar-btn {
          padding: 12px 25px;
          font-size: 1rem;
          font-weight: 500;
          border-radius: 8px;
          display: flex;
          align-items: center;
          justify-content: center;
          transition: all 0.3s;
          cursor: pointer;
          border: none;
          background: rgba(255, 255, 255, 0.15);
          color: white;
      }

      .toolbar-btn:hover {
          background: rgba(255, 255, 255, 0.25);
          transform: translateY(-2px);
      }

      .toolbar-btn i {
          margin-right: 10px;
          font-size: 1.2rem;
      }

      .save-btn {
          background: linear-gradient(135deg, #43cea2 0%, #3498db 100%);
      }

      .execute-btn {
          background: linear-gradient(135deg, #FF512F 0%, #F09819 100%);
      }

      /* 主内容区 - 新布局 */
      .main-content {
          flex: 1;
          padding: 25px;
          display: grid;
          grid-template-areas:
              "pipeline database"
              "preview preview"
              "details details";
          grid-template-columns: 1fr 1fr;
          grid-template-rows: auto 1fr auto;
          gap: 25px;
          height: calc(100vh - 90px);
      }

      .pipeline-section {
          grid-area: pipeline;
      }

      .preview-section {
          grid-area: preview;
      }

      .details-section {
          grid-area: details;
      }

      .database-section {
          grid-area: database;
      }

      /* 流水线标题 */
      .pipeline-title {
          font-size: 1.6rem;
          font-weight: bold;
          display: flex;
          align-items: center;
          color: #2d3748;
          margin-bottom: 20px;
          padding-bottom: 15px;
          border-bottom: 2px solid #edf2f7;
      }

      .pipeline-title i {
          margin-right: 12px;
          color: var(--step-1-color);
          font-size: 1.8rem;
      }

      /* 流水线步骤容器 */
      .pipeline-container {
          display: flex;
          gap: 20px;
          overflow-x: auto;
          padding: 15px 0;
          flex-wrap: nowrap;
          background: white;
          border-radius: 12px;
          box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
          padding: 20px;
          border: 1px solid var(--border-color);
      }

      /* 步骤卡片 */
      .step-card {
          min-width: 350px;
          background: var(--card-bg);
          border-radius: 12px;
          box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
          transition: all 0.3s;
          cursor: pointer;
          border: 1px solid var(--border-color);
          overflow: hidden;
          flex-shrink: 0;
      }

      .step-card.active {
          transform: translateY(-5px);
          box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15);
          border: 2px solid;
          border-top-width: 5px;
      }

      .step-card.step-1.active {
          border-color: var(--step-1-color);
          border-top-color: var(--step-1-color);
      }

      .step-card.step-2.active {
          border-color: var(--step-2-color);
          border-top-color: var(--step-2-color);
      }

      .step-card.step-3.active {
          border-color: var(--step-3-color);
          border-top-color: var(--step-3-color);
      }

      .step-card.step-4.active {
          border-color: var(--step-4-color);
          border-top-color: var(--step-4-color);
      }

      .step-header {
          padding: 18px;
          background: var(--header-bg);
          font-weight: 600;
          display: flex;
          align-items: center;
          position: relative;
      }

      .step-header.step-1 {
          background-color: rgba(66, 134, 244, 0.1);
          border-left: 5px solid var(--step-1-color);
      }

      .step-header.step-2 {
          background-color: rgba(255, 140, 0, 0.1);
          border-left: 5px solid var(--step-2-color);
      }

      .step-header.step-3 {
          background-color: rgba(67, 206, 162, 0.1);
          border-left: 5px solid var(--step-3-color);
      }

      .step-header.step-4 {
          background-color: rgba(156, 39, 176, 0.1);
          border-left: 5px solid var(--step-4-color);
      }

      .step-icon {
          width: 36px;
          height: 36px;
          display: flex;
          align-items: center;
          justify-content: center;
          border-radius: 50%;
          margin-right: 15px;
          font-size: 1.1rem;
          background: rgba(255, 255, 255, 0.9);
      }

      .step-icon.step-1 {
          background-color: var(--step-1-color);
          color: white;
      }

      .step-icon.step-2 {
          background-color: var(--step-2-color);
          color: white;
      }

      .step-icon.step-3 {
          background-color: var(--step-3-color);
          color: white;
      }

      .step-icon.step-4 {
          background-color: var(--step-4-color);
          color: white;
      }

      .step-info {
          flex: 1;
      }

      .step-name {
          font-size: 1.2rem;
          color: #2d3748;
          font-weight: 600;
      }

      .step-desc {
          font-size: 0.9rem;
          color: #718096;
      }

      /* 列变化表格 */
      .schema-container {
          padding: 0 18px 18px;
      }

      .columns-table {
          width: 100%;
          border-collapse: collapse;
          border-radius: 10px;
          overflow: hidden;
      }

      .columns-table th, .columns-table td {
          padding: 14px;
          text-align: left;
      }

      .columns-table th {
          background-color: var(--table-header-bg);
          font-weight: 600;
          font-size: 0.9rem;
          color: #4a5568;
          white-space: nowrap;
      }

      .columns-table tbody tr {
          transition: all 0.2s ease;
      }

      /* 图标样式 */
      .column-icon {
          display: inline-flex;
          justify-content: center;
          align-items: center;
          width: 26px;
          height: 26px;
          border-radius: 5px;
          margin-right: 10px;
      }

      .icon-added {
          background-color: #2e7d32;
          color: white;
      }

      .icon-removed {
          background-color: #c62828;
          color: white;
      }

      .icon-modified {
          background-color: #ef6c00;
          color: white;
      }

      .icon-split {
          background-color: #0288d1;
          color: white;
      }

      .icon-aggregate {
          background-color: #7b1fa2;
          color: white;
      }

      .icon-none {
          visibility: hidden;
      }

      /* 列名样式 */
      .column-name {
          font-weight: 500;
          color: #2d3748;
          display: flex;
          align-items: center;
          font-size: 1rem;
      }

      .removed-column {
          text-decoration: line-through;
          color: #c62828;
          opacity: 0.7;
      }

      /* 为不同变化类型添加背景色 */
      .row-added {
          background-color: var(--added-color);
          border-left: 4px solid #2e7d32;
      }

      .row-modified {
          background-color: var(--modified-color);
          border-left: 4px solid #ef6c00;
      }

      .row-removed {
          background-color: var(--removed-color);
          border-left: 4px solid #c62828;
      }

      .row-split {
          background-color: var(--split-color);
          border-left: 4px solid #0288d1;
      }

      .row-aggregate {
          background-color: var(--aggregate-color);
          border-left: 4px solid #7b1fa2;
      }

      .row-added td, .row-modified td, .row-removed td,
      .row-split td, .row-aggregate td {
          border-bottom: 1px solid rgba(0,0,0,0.05);
      }

      .columns-table tr:last-child td {
          border-bottom: none;
      }

      .columns-table tr:hover {
          transform: translateX(3px);
          background-color: rgba(0, 0, 0, 0.02);
      }

      .columns-table .row-added:hover {
          background-color: color-mix(in srgb, var(--added-color) 80%, white);
      }

      .columns-table .row-modified:hover {
          background-color: color-mix(in srgb, var(--modified-color) 80%, white);
      }

      .columns-table .row-removed:hover {
          background-color: color-mix(in srgb, var(--removed-color) 80%, white);
      }

      .columns-table .row-split:hover {
          background-color: color-mix(in srgb, var(--split-color) 80%, white);
      }

      .columns-table .row-aggregate:hover {
          background-color: color-mix(in srgb, var(--aggregate-color) 80%, white);
      }

      /* 数据预览区域 */
      .data-preview {
          height: 100%;
          display: flex;
          flex-direction: column;
          background: white;
          border-radius: 12px;
          box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
          border: 1px solid var(--border-color);
      }

      .preview-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 20px;
          border-bottom: 1px solid var(--border-color);
      }

      .preview-title {
          font-size: 1.4rem;
          font-weight: 600;
          display: flex;
          align-items: center;
      }

      .preview-title i {
          margin-right: 12px;
          color: var(--step-1-color);
          font-size: 1.5rem;
      }

      .data-stats {
          display: flex;
          gap: 18px;
      }

      .stat-card {
          padding: 12px 18px;
          border-radius: 10px;
          background: #f0f8ff;
          display: flex;
          flex-direction: column;
          align-items: center;
          min-width: 100px;
          box-shadow: 0 3px 8px rgba(0,0,0,0.05);
      }

      .stat-value {
          font-size: 1.3rem;
          font-weight: 700;
          margin-bottom: 5px;
          color: #2d3748;
      }

      .stat-label {
          font-size: 0.9rem;
          color: #718096;
      }

      /* 数据表格 */
      .data-table-container {
          flex: 1;
          overflow: auto;
          background: white;
      }

      .data-table {
          width: 100%;
          border-collapse: collapse;
      }

      .data-table th {
          padding: 14px 18px;
          text-align: left;
          font-weight: 600;
          font-size: 0.9rem;
          color: #4a5568;
          position: sticky;
          top: 0;
          background: #f8f9fa;
      }

      .data-table td {
          padding: 14px 18px;
          font-size: 0.95rem;
          border-bottom: 1px solid #edf2f7;
          color: #4a5568;
      }

      .data-table tr:nth-child(even) {
          background-color: #f9fafb;
      }

      /* 变化列标记 */
      .col-added {
          background-color: var(--added-color);
          position: relative;
      }

      .col-added::after {
          content: '+';
          position: absolute;
          top: 5px;
          right: 5px;
          font-size: 10px;
          background: #4caf50;
          color: white;
          width: 18px;
          height: 18px;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
      }

      .col-modified {
          background-color: var(--modified-color);
          position: relative;
      }

      .col-modified::after {
          content: '↻';
          position: absolute;
          top: 5px;
          right: 5px;
          font-size: 10px;
          background: #ff9800;
          color: white;
          width: 18px;
          height: 18px;
          border-radius: 50%;
          display: flex;
          align-items:  center;
          justify-content: center;
      }

      .col-removed {
          background-color: var(--removed-color);
          opacity: 0.7;
      }

      /* 数据库面板 */
      .database-panel {
          height: 100%;
          display: flex;
          flex-direction: column;
          background: white;
          border-radius: 12px;
          box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
          border: 1px solid var(--border-color);
      }

      .database-header {
          padding: 20px;
          border-bottom: 1px solid var(--border-color);
      }

      .database-title {
          font-size: 1.4rem;
          font-weight: 600;
          display: flex;
          align-items: center;
      }

      .database-title i {
          margin-right: 12px;
          color: var(--step-4-color);
          font-size: 1.5rem;
      }

      /* 树形结构样式 */
      .db-tree {
          padding: 15px;
          max-height: 300px;
          overflow-y: auto;
          border-bottom: 1px solid var(--border-color);
      }

      .tree-node {
          margin: 5px 0;
      }

      .tree-content {
          display: flex;
          align-items: center;
          padding: 8px 12px;
          border-radius: 6px;
          transition: all 0.2s;
          cursor: pointer;
      }

      .tree-content:hover {
          background: #f0f7ff;
      }

      .tree-content.selected {
          background: #e3f2fd;
          border: 1px solid var(--panel-color);
      }

      .tree-toggle {
          width: 24px;
          height: 24px;
          display: flex;
          align-items: center;
          justify-content: center;
          margin-right: 8px;
          color: var(--panel-color);
          transition: transform 0.2s;
      }

      .tree-toggle.expanded {
          transform: rotate(90deg);
      }

      .tree-icon {
          margin-right: 8px;
          color: var(--panel-color);
      }

      .tree-label {
          flex: 1;
          font-size: 0.95rem;
      }

      .tree-type {
          color: #666;
          font-size: 0.85rem;
          margin-left: 8px;
      }

      .tree-children {
          margin-left: 32px;
          display: none;
      }

      .tree-children.expanded {
          display: block;
      }

      /* 字段比对表样式 */
      .field-comparison {
          margin-top: 15px;
          padding: 15px;
          border-top: 1px solid var(--border-color);
      }

      .comparison-title {
          font-size: 1.1rem;
          font-weight: 600;
          margin-bottom: 15px;
          display: flex;
          align-items: center;
          justify-content: space-between;
      }

      .comparison-table {
          width: 100%;
          border-collapse: collapse;
      }

      .comparison-table th {
          background: #f8f9fa;
          padding: 12px;
          text-align: left;
          font-weight: 600;
          border-bottom: 2px solid var(--border-color);
      }

      .comparison-table td {
          padding: 12px;
          border-bottom: 1px solid var(--border-color);
      }

      .comparison-table tr:hover {
          background: #f8f9fa;
      }

      .match-indicator {
          padding: 4px 8px;
          border-radius: 4px;
          font-size: 0.85rem;
          font-weight: 500;
      }

      .match-yes {
          background: #e8f5e9;
          color: #2e7d32;
      }

      .match-no {
          background: #ffebee;
          color: #c62828;
      }

      /* 数据库列信息 */
      .db-columns-container {
          padding: 15px;
          flex: 1;
          overflow: auto;
          display: flex;
          flex-direction: column;
      }

      .db-columns-title {
          font-size: 1.1rem;
          font-weight: 600;
          margin-bottom: 15px;
          padding-bottom: 10px;
          border-bottom: 1px solid var(--border-color);
          display: flex;
          align-items: center;
          justify-content: space-between;
      }

      .db-columns-table {
          width: 100%;
          border-collapse: collapse;
          flex: 1;
      }

      .db-columns-table th {
          padding: 12px 15px;
          text-align: left;
          font-weight: 600;
          font-size: 0.9rem;
          color: #4a5568;
          position: sticky;
          top: 0;
          background: #f8f9fa;
      }

      .db-columns-table td {
          padding: 12px 15px;
          font-size: 0.9rem;
          border-bottom: 1px solid #edf2f7;
      }

      .db-columns-table tr.column-match {
          background-color: var(--highlight-color);
      }

      .db-columns-table tr.column-mismatch {
          background-color: var(--missing-color);
          color: var(--gray-text);
      }

      /* 状态标记 */
      .match-status {
          padding: 5px 10px;
          border-radius: 4px;
          font-size: 0.9rem;
          font-weight: 500;
      }

      .status-match {
          background: #e8f5e9;
          color: #2e7d32;
      }

      .status-mismatch {
          background: #ffebee;
          color: #c62828;
      }

      /* 清洗与转换节点详情面板 */
      .transform-details-panel {
          height: 100%;
          display: flex;
          flex-direction: column;
          background: white;
          border-radius: 12px;
          box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
          border: 1px solid var(--border-color);
      }

      .panel-header {
          padding: 20px;
          border-bottom: 1px solid var(--border-color);
          font-size: 1.4rem;
          font-weight: 600;
          display: flex;
          align-items: center;
          color: var(--panel-color);
      }

      .panel-header i {
          margin-right: 12px;
          color: var(--panel-color);
          font-size: 1.5rem;
      }

      .panel-header-text {
          font-size: 1.5rem;
      }

      /* 选项卡样式 */
      .detail-tabs {
          display: flex;
          margin: 0 20px 20px;
          border-bottom: 1px solid var(--border-color);
      }

      .tab {
          padding: 14px 24px;
          cursor: pointer;
          font-weight: 500;
          transition: all 0.3s;
          position: relative;
          color: var(--tab-inactive);
          font-size: 1.05rem;
      }

      .tab.active {
          color: var(--tab-active);
          border-bottom: 3px solid var(--tab-active);
          font-weight: 600;
      }

      /* 概览卡片容器 */
      .overview-container {
          display: grid;
          grid-template-columns: repeat(4, 1fr);
          gap: 18px;
          margin-bottom: 25px;
          padding: 0 20px;
      }

      .overview-card {
          background: #f8f9fa;
          border-radius: 12px;
          padding: 18px;
          text-align: center;
          transition: all 0.3s;
          border: 1px solid var(--border-color);
          box-shadow: 0 3px 8px rgba(0,0,0,0.05);
      }

      .overview-card:hover {
          transform: translateY(-3px);
          box-shadow: 0 6px 12px rgba(0,0,0,0.1);
      }

      .overview-value {
          font-size: 1.9rem;
          font-weight: 700;
          color: var(--panel-color);
          margin: 12px 0;
      }

      .overview-label {
          font-size: 0.95rem;
          color: #666;
      }

      /* 列详细信息表格 */
      .details-table-container {
          border: 1px solid var(--border-color);
          border-radius: 10px;
          overflow: auto;
          flex: 1;
          margin: 0 20px 20px;
      }

      .details-table {
          width: 100%;
          border-collapse: collapse;
      }

      .details-table th {
          background-color: var(--panel-color);
          color: white;
          padding: 14px 18px;
          text-align: left;
          font-weight: 600;
          font-size: 0.95rem;
      }

      .details-table td {
          padding: 14px 18px;
          border-bottom: 1px solid var(--border-color);
          font-size: 0.95rem;
      }

      .details-table tr:nth-child(even) {
          background-color: #f9f9f9;
      }

      /* 图例面板 */
      .legend-panel {
          background: white;
          border-radius: 10px;
          padding: 18px;
          margin: 20px;
          border: 1px solid var(--border-color);
          box-shadow: 0 3px 8px rgba(0,0,0,0.05);
      }

      .legend-title {
          font-weight: 600;
          margin-bottom: 12px;
          color: #333;
          display: flex;
          align-items: center;
          font-size: 1.1rem;
      }

      .legend-title i {
          margin-right: 10px;
          color: var(--panel-color);
      }

      .legend-items {
          display: grid;
          grid-template-columns: repeat(3, 1fr);
          gap: 15px;
      }

      .legend-item {
          display: flex;
          align-items: center;
          font-size: 0.9rem;
      }

      .legend-icon {
          width: 24px;
          height: 24px;
          border-radius: 5px;
          margin-right: 10px;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 0.8rem;
          color: white;
      }

  </style>
</head>
<body>
<div class="app-container">
  <!-- 顶部工具条 -->
  <div class="toolbar">
    <div class="toolbar-title">
      <i class="fas fa-random"></i>
      <span>数据集处理流水线可视化系统</span>
    </div>
    <div class="toolbar-buttons">
      <button class="toolbar-btn">
        <i class="fas fa-plus"></i>
        <span>新流水线</span>
      </button>
      <button class="toolbar-btn">
        <i class="fas fa-history"></i>
        <span>历史版本</span>
      </button>
      <button class="toolbar-btn save-btn">
        <i class="fas fa-save"></i>
        <span>保存</span>
      </button>
      <button class="toolbar-btn execute-btn">
        <i class="fas fa-play"></i>
        <span>执行流水线</span>
      </button>
    </div>
  </div>

  <!-- 主内容区 -->
  <div class="main-content">
    <!-- 流水线区域 -->
    <div class="pipeline-section">
      <div class="pipeline-title">
        <i class="fas fa-project-diagram"></i>
        数据集处理流水线
      </div>

      <!-- 字段变化图例 -->
      <div class="legend-panel">
        <div class="legend-items">
          <div class="legend-item">
            <div class="legend-icon icon-added">
              <i class="fas fa-plus"></i>
            </div>
            <div>新增字段</div>
          </div>
          <div class="legend-item">
            <div class="legend-icon icon-modified">
              <i class="fas fa-sync-alt"></i>
            </div>
            <div>修改字段</div>
          </div>
          <div class="legend-item">
            <div class="legend-icon icon-removed">
              <i class="fas fa-trash"></i>
            </div>
            <div>删除字段</div>
          </div>
          <div class="legend-item">
            <div class="legend-icon icon-split">
              <i class="fas fa-cut"></i>
            </div>
            <div>拆分操作</div>
          </div>
          <div class="legend-item">
            <div class="legend-icon icon-aggregate">
              <i class="fas fa-object-group"></i>
            </div>
            <div>聚合操作</div>
          </div>
        </div>
      </div>

      <!-- 流水线步骤卡片 -->
      <div class="pipeline-container">
        <!-- 步骤1: 源数据 -->
        <div class="step-card step-1 active" data-step="1">
          <div class="step-header step-1">
            <div class="step-icon step-1">
              <i class="fas fa-database"></i>
            </div>
            <div class="step-info">
              <div class="step-name">源数据表</div>
              <div class="step-desc">原始客户数据</div>
            </div>
          </div>
          <div class="schema-container">
            <table class="columns-table">
              <thead>
              <tr>
                <th>字段名称</th>
                <th>字段类型</th>
                <th>是否必填</th>
                <th>数据类型</th>
              </tr>
              </thead>
              <tbody>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  cust_id
                </td>
                <td>用户标识</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(20)</td>
              </tr>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  姓名
                </td>
                <td>用户信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(50)</td>
              </tr>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  电话
                </td>
                <td>联系信息</td>
                  <td><i class="fas fa-times-circle" style="color:#f44336;"></i> 否</td>
                  <td>VARCHAR(15)</td>
              </tr>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  地址
                </td>
                <td>地理信息</td>
                <td><i class="fas fa-times-circle" style="color:#f44336;"></i> 否</td>
                <td>VARCHAR(200)</td>
              </tr>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  注册日期
                </td>
                <td>时间信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>DATE</td>
              </tr>
              </tbody>
            </table>
          </div>
        </div>

        <!-- 步骤2: 清洗转换 -->
        <div class="step-card step-2" data-step="2">
          <div class="step-header step-2">
            <div class="step-icon step-2">
              <i class="fas fa-filter"></i>
            </div>
            <div class="step-info">
              <div class="step-name">清洗转换表</div>
              <div class="step-desc">清洗后客户数据</div>
            </div>
          </div>
          <div class="schema-container">
            <table class="columns-table">
              <thead>
              <tr>
                <th>字段名称</th>
                <th>字段类型</th>
                <th>是否必填</th>
                <th>数据类型</th>
              </tr>
              </thead>
              <tbody>
              <tr class="row-modified">
                <td class="column-name">
                    <span class="column-icon icon-modified">
                      <i class="fas fa-sync-alt"></i>
                    </span>
                  customer_id
                </td>
                <td>用户标识</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(20)</td>
              </tr>
              <tr class="row-modified">
                <td class="column-name">
                    <span class="column-icon icon-modified">
                      <i class="fas fa-object-group"></i>
                    </span>
                  full_name
                </td>
                <td>用户信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(50)</td>
              </tr>
              <tr class="row-split">
                <td class="column-name">
                    <span class="column-icon icon-split">
                      <i class="fas fa-cut"></i>
                    </span>
                  province
                </td>
                <td>地理信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(20)</td>
              </tr>
              <tr class="row-split">
                <td class="column-name">
                    <span class="column-icon icon-split">
                      <i class="fas fa-cut"></i>
                    </span>
                  city
                </td>
                <td>地理信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(30)</td>
              </tr>
              <tr class="row-modified">
                <td class="column-name">
                    <span class="column-icon icon-modified">
                      <i class="fas fa-sync-alt"></i>
                    </span>
                  register_date
                </td>
                <td>时间信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>DATE</td>
              </tr>
              <tr class="row-removed">
                <td class="column-name">
                    <span class="column-icon icon-removed">
                      <i class="fas fa-trash"></i>
                    </span>
                  <span class="removed-column">电话</span>
                </td>
                <td>联系信息</td>
                <td><i class="fas fa-times-circle" style="color:#f44336;"></i> 否</td>
                <td>VARCHAR(15)</td>
              </tr>
              </tbody>
            </table>
          </div>
        </div>

        <!-- 步骤3: 数据增强 -->
        <div class="step-card step-3" data-step="3">
          <div class="step-header step-3">
            <div class="step-icon step-3">
              <i class="fas fa-chart-line"></i>
            </div>
            <div class="step-info">
              <div class="step-name">增强数据表</div>
              <div class="step-desc">添加衍生特征</div>
            </div>
          </div>
          <div class="schema-container">
            <table class="columns-table">
              <thead>
              <tr>
                <th>字段名称</th>
                <th>字段类型</th>
                <th>是否必填</th>
                <th>数据类型</th>
              </tr>
              </thead>
              <tbody>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  customer_id
                </td>
                <td>用户标识</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(20)</td>
              </tr>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  full_name
                </td>
                <td>用户信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(50)</td>
              </tr>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  province
                </td>
                <td>地理信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(20)</td>
              </tr>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  city
                </td>
                <td>地理信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>VARCHAR(30)</td>
              </tr>
              <tr>
                <td class="column-name">
                  <span class="column-icon icon-none"></span>
                  register_date
                </td>
                <td>时间信息</td>
                <td><i class="fas fa-check-circle" style="color:#4caf50;"></i> 是</td>
                <td>DATE</td>
              </tr>
              <tr class="row-added">
                <td class="column-name">
                    <span class="column-icon icon-added">
                      <i class="fas fa-plus"></i>
                    </span>
                  loyalty_level
                </td>
                <td>用户属性</td>
                <td><i class="fas fa-times-circle" style="color:#f44336;"></i> 否</td>
                <td>VARCHAR(10)</td>
              </tr>
              <tr class="row-aggregate">
                <td class="column-name">
                    <span class="column-icon icon-aggregate">
                      <i class="fas fa-object-group"></i>
                    </span>
                  customer_value
                </td>
                <td>业务指标</td>
                <td><i class="fas fa-times-circle" style="color:#f44336;"></i> 否</td>
                <td>DECIMAL(10,2)</td>
              </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div> <!-- 结束流水线步骤容器 -->
    </div> <!-- 结束流水线区域 -->


    <!-- 数据处理详情区域 -->
    <div class="details-section">
      <div class="transform-details-panel">
        <div class="panel-header">
          <i class="fas fa-exchange-alt"></i>
          <div class="panel-header-text">数据集详情 - 清洗与转换节点</div>
        </div>

        <!-- 选项卡 -->
        <div class="detail-tabs">
          <div class="tab active">数据集结构</div>
          <div class="tab">转换规则</div>
          <div class="tab">数据质量</div>
        </div>

        <!-- 概览卡片 -->
        <div class="overview-container">
          <div class="overview-card">
            <div class="overview-value">7</div>
            <div class="overview-label">列数量</div>
          </div>
          <div class="overview-card">
            <div class="overview-value">192K</div>
            <div class="overview-label">总记录数</div>
          </div>
          <div class="overview-card">
            <div class="overview-value">98.7%</div>
            <div class="overview-label">质量评分</div>
          </div>
          <div class="overview-card">
            <div class="overview-value">3</div>
            <div class="overview-label">处理步骤</div>
          </div>
        </div>

        <!-- 列详细信息表格 -->
        <div class="details-table-container">
          <table class="details-table">
            <thead>
            <tr>
              <th>列名</th>
              <th>字段类型</th>
              <th>是否必填</th>
              <th>数据类型</th>
              <th>转换来源</th>
            </tr>
            </thead>
            <tbody>
            <tr>
              <td>customer_id</td>
              <td>用户标识</td>
              <td>是</td>
              <td>string(10)</td>
              <td>原始列: cust_id</td>
            </tr>
            <tr>
              <td>full_name</td>
              <td>用户信息</td>
              <td>是</td>
              <td>string(50)</td>
              <td>原始列: 姓名</td>
            </tr>
            <tr>
              <td>province</td>
              <td>地理信息</td>
              <td>是</td>
              <td>string(20)</td>
              <td>拆分列 (从地址拆分)</td>
            </tr>
            <tr>
              <td>city</td>
              <td>地理信息</td>
              <td>是</td>
              <td>string(30)</td>
              <td>拆分列 (从地址拆分)</td>
            </tr>
            <tr>
              <td>register_date</td>
              <td>时间信息</td>
              <td>是</td>
              <td>date</td>
              <td>原始列: 注册日期</td>
            </tr>
            <tr>
              <td>loyalty_level</td>
              <td>用户属性</td>
              <td>否</td>
              <td>string(10)</td>
              <td>新增列 (基于交易计算)</td>
            </tr>
            <tr>
              <td>customer_value</td>
              <td>业务指标</td>
              <td>否</td>
              <td>float</td>
              <td>聚合列 (交易聚合值)</td>
            </tr>
            </tbody>
          </table>
        </div>

        <!-- 图例面板已移至流水线标题下方 -->
      </div>
    </div> <!-- 结束数据处理区域 -->

    <!-- 数据库区域 -->
    <div class="database-section">
      <div class="database-panel">
        <div class="database-header">
          <div class="database-title">
            <i class="fas fa-database"></i>
            数据库表结构
          </div>
        </div>

        <!-- 树形结构 -->
        <div class="db-tree">
          <!-- 树节点将由JavaScript动态生成 -->
        </div>

        <!-- 字段比对表 -->
        <div class="field-comparison">
          <div class="comparison-title">
            <span>字段映射比对 - <span class="highlight">客户信息表</span></span>
            <div class="match-status"></div>
          </div>
          <table class="comparison-table">
            <thead>
              <tr>
                <th>数据集字段</th>
                <th>目标表字段</th>
                <th>是否匹配</th>
                <th>数据类型</th>
              </tr>
            </thead>
            <tbody>
              <!-- 比对结果将由JavaScript动态生成 -->
            </tbody>
          </table>
        </div>
      </div>
    </div> <!-- 结束数据库区域 -->
  </div> <!-- 结束主内容区 -->
</div>

<script>
  // 数据库表结构定义
  const dbTables = {
    "客户信息表": [
      {name: "客户ID", type: "VARCHAR(20)", required: true, fieldType: "用户标识"},
      {name: "姓名", type: "VARCHAR(50)", required: true, fieldType: "用户信息"},
      {name: "省份", type: "VARCHAR(20)", required: true, fieldType: "地理信息"},
      {name: "城市", type: "VARCHAR(30)", required: true, fieldType: "地理信息"},
      {name: "注册日期", type: "DATE", required: true, fieldType: "时间信息"},
      {name: "客户等级", type: "VARCHAR(10)", required: false, fieldType: "用户属性"},
      {name: "客户价值", type: "DECIMAL(10,2)", required: false, fieldType: "业务指标"},
      {name: "联系方式", type: "VARCHAR(50)", required: true, fieldType: "联系信息"}
    ],
    "交易记录表": [
      {name: "交易ID", type: "BIGINT", required: true, fieldType: "交易标识"},
      {name: "客户ID", type: "VARCHAR(20)", required: true, fieldType: "用户标识"},
      {name: "交易金额", type: "DECIMAL(10,2)", required: true, fieldType: "交易信息"},
      {name: "交易日期", type: "DATETIME", required: true, fieldType: "时间信息"},
      {name: "支付方式", type: "VARCHAR(20)", required: false, fieldType: "交易信息"}
    ],
    "用户行为表": [
      {name: "行为ID", type: "BIGINT", required: true, fieldType: "行为标识"},
      {name: "客户ID", type: "VARCHAR(20)", required: true, fieldType: "用户标识"},
      {name: "行为类型", type: "VARCHAR(20)", required: true, fieldType: "行为属性"},
      {name: "行为时间", type: "DATETIME", required: true, fieldType: "时间信息"},
      {name: "页面路径", type: "VARCHAR(200)", required: false, fieldType: "页面信息"}
    ]
  };

  // 数据集字段定义
  const datasetFields = {
    "1": [ // 源数据
      {name: "cust_id", type: "VARCHAR(20)", required: true, fieldType: "用户标识"},
      {name: "姓名", type: "VARCHAR(50)", required: true, fieldType: "用户信息"},
      {name: "电话", type: "VARCHAR(15)", required: false, fieldType: "联系信息"},
      {name: "地址", type: "VARCHAR(200)", required: false, fieldType: "地理信息"},
      {name: "注册日期", type: "DATE", required: true, fieldType: "时间信息"}
    ],
    "2": [ // 清洗转换
      {name: "customer_id", type: "VARCHAR(20)", required: true, fieldType: "用户标识"},
      {name: "full_name", type: "VARCHAR(50)", required: true, fieldType: "用户信息"},
      {name: "province", type: "VARCHAR(20)", required: true, fieldType: "地理信息"},
      {name: "city", type: "VARCHAR(30)", required: true, fieldType: "地理信息"},
      {name: "register_date", type: "DATE", required: true, fieldType: "时间信息"}
    ],
    "3": [ // 数据增强
      {name: "customer_id", type: "VARCHAR(20)", required: true, fieldType: "用户标识"},
      {name: "full_name", type: "VARCHAR(50)", required: true, fieldType: "用户信息"},
      {name: "province", type: "VARCHAR(20)", required: true, fieldType: "地理信息"},
      {name: "city", type: "VARCHAR(30)", required: true, fieldType: "地理信息"},
      {name: "register_date", type: "DATE", required: true, fieldType: "时间信息"},
      {name: "loyalty_level", type: "VARCHAR(10)", required: false, fieldType: "用户属性"},
      {name: "customer_value", type: "DECIMAL(10,2)", required: false, fieldType: "业务指标"}
    ]
  };

  // 初始化树形结构
  function initializeTree() {
    const dbTree = document.querySelector('.db-tree');
    dbTree.innerHTML = '';

    Object.entries(dbTables).forEach(([tableName, fields]) => {
      const node = document.createElement('div');
      node.className = 'tree-node';
      node.innerHTML = `
        <div class="tree-content">
          <div class="tree-toggle">
            <i class="fas fa-chevron-right"></i>
          </div>
          <i class="fas fa-table tree-icon"></i>
          <span class="tree-label">${tableName}</span>
        </div>
        <div class="tree-children">
          ${fields.map(field => `
            <div class="tree-node">
              <div class="tree-content">
                <i class="fas fa-columns tree-icon"></i>
                <span class="tree-label">${field.name}</span>
                <span class="tree-type">${field.type}</span>
              </div>
            </div>
          `).join('')}
        </div>
      `;

      // 添加展开/折叠功能
      const toggle = node.querySelector('.tree-toggle');
      const content = node.querySelector('.tree-content');
      const children = node.querySelector('.tree-children');

      toggle.addEventListener('click', (e) => {
        e.stopPropagation();
        toggle.classList.toggle('expanded');
        children.classList.toggle('expanded');
      });

      // 添加表选择功能
      content.addEventListener('click', () => {
        document.querySelectorAll('.tree-content').forEach(el => {
          el.classList.remove('selected');
        });
        content.classList.add('selected');
        updateFieldComparison(tableName);
      });

      dbTree.appendChild(node);
    });
  }

  // 更新字段比对表
  function updateFieldComparison(tableName) {
    const currentStep = document.querySelector('.step-card.active').dataset.step;
    const currentFields = datasetFields[currentStep];
    const tableFields = dbTables[tableName];

    // 更新标题
    document.querySelector('.field-comparison .highlight').textContent = tableName;

    // 更新比对表
    const tbody = document.querySelector('.comparison-table tbody');
    tbody.innerHTML = '';

    currentFields.forEach(field => {
      const matchingField = findMatchingField(field, tableFields);
      const row = document.createElement('tr');
      row.innerHTML = `
        <td>${field.name}</td>
        <td>${matchingField ? matchingField.name : '-'}</td>
        <td>
          <span class="match-indicator ${matchingField ? 'match-yes' : 'match-no'}">
            ${matchingField ? '匹配' : '未匹配'}
          </span>
        </td>
        <td>${field.type} → ${matchingField ? matchingField.type : '-'}</td>
      `;
      tbody.appendChild(row);
    });

    // 更新匹配状态
    const matchCount = currentFields.filter(f => findMatchingField(f, tableFields)).length;
    const matchRate = Math.round((matchCount / currentFields.length) * 100);
    document.querySelector('.match-status').innerHTML = `
      <span class="match-indicator ${matchRate > 70 ? 'match-yes' : 'match-no'}">
        匹配率: ${matchRate}% (${matchCount}/${currentFields.length})
      </span>
    `;
  }

  // 查找匹配字段
  function findMatchingField(datasetField, tableFields) {
    // 字段名称映射关系
    const fieldMappings = {
      'cust_id': '客户ID',
      'customer_id': '客户ID',
      'full_name': '姓名',
      'province': '省份',
      'city': '城市',
      'register_date': '注册日期',
      'loyalty_level': '客户等级',
      'customer_value': '客户价值',
      '电话': '联系方式'
    };

    // 尝试直接匹配或通过映射匹配
    return tableFields.find(field =>
      field.name === datasetField.name ||
      field.name === fieldMappings[datasetField.name] ||
      datasetField.name === fieldMappings[field.name]
    );
  }

  // 步骤卡片交互
  document.querySelectorAll('.step-card').forEach(card => {
    card.addEventListener('click', function() {
      const step = this.dataset.step;
      document.querySelectorAll('.step-card').forEach(c => c.classList.remove('active'));
      this.classList.add('active');

      // 更新数据预览
      updateDataPreview(step);

      // 更新字段比对
      const selectedTable = document.querySelector('.tree-content.selected');
      if (selectedTable) {
        const tableName = selectedTable.querySelector('.tree-label').textContent;
        updateFieldComparison(tableName);
      }
    });
  });

  // 选项卡交互
  document.querySelectorAll('.tab').forEach(tab => {
    tab.addEventListener('click', function() {
      document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
      this.classList.add('active');
    });
  });

  // 定义每个步骤各列的变化类型
  const columnChanges = {
    "1": {
      "地址": "modified",
      "姓名": "modified"
    },
    "2": {
      "customer_id": "modified",
      "full_name": "aggregate",
      "province": "split",
      "city": "split",
      "register_date": "modified",
      "电话": "removed"
    },
    "3": {
      "customer_id": "none",
      "full_name": "none",
      "province": "none",
      "city": "none",
      "register_date": "none",
      "loyalty_level": "added",
      "customer_value": "aggregate"
    }
  };

  // 更新数据预览函数
  function updateDataPreview(step) {
    let previewTitle = "";
    let headers = [];
    let dataRows = [];

    switch(step) {
      case "1": // 源数据
        previewTitle = "源数据表 - 实际数据预览";
        headers = ["cust_id", "姓名", "电话", "地址", "注册日期"];
        dataRows = [
          ["C1001", "张三", "13800138000", "北京市海淀区中关村大街1号", "2020-05-12"],
          ["C1002", "李四", "13900139000", "上海市浦东新区张江高科技园区", "2021-03-22"],
          ["C1003", "王五", "13700137000", "广州市天河区珠江新城", "2019-11-15"],
          ["C1004", "赵六", "13500135000", "深圳市福田区华强北路", "2020-08-09"],
          ["C1005", "钱七", "13600136000", "杭州市西湖区文三路", "2021-07-15"]
        ];
        break;

      case "2": // 清洗转换
        previewTitle = "清洗转换表 - 实际数据预览";
        headers = ["customer_id", "full_name", "province", "city", "register_date"];
        dataRows = [
          ["C1001", "张三", "北京", "北京市", "2020-05-12"],
          ["C1002", "李四", "上海", "上海市", "2021-03-22"],
          ["C1003", "王五", "广东", "广州市", "2019-11-15"],
          ["C1004", "赵六", "广东", "深圳市", "2020-08-09"],
          ["C1005", "钱七", "浙江", "杭州市", "2021-07-15"]
        ];
        break;

      case "3": // 数据增强
        previewTitle = "增强数据表 - 实际数据预览";
        headers = ["customer_id", "full_name", "province", "city", "register_date", "loyalty_level", "customer_value"];
        dataRows = [
          ["C1001", "张三", "北京", "北京市", "2020-05-12", "金卡", "15842.50"],
          ["C1002", "李四", "上海", "上海市", "2021-03-22", "银卡", "7820.40"],
          ["C1003", "王五", "广东", "广州市", "2019-11-15", "钻石卡", "28570.80"],
          ["C1004", "赵六", "广东", "深圳市", "2020-08-09", "普通", "28570.90"],
          ["C1005", "钱七", "浙江", "杭州市", "2021-07-15", "白金卡", "18720.30"]
        ];
        break;
    }

    // 更新预览标题
    document.querySelector('.preview-title').innerHTML = `
          <i class="fas fa-table"></i>
          ${previewTitle}
        `;

    // 更新表格
    const table = document.querySelector('.data-table');
    table.innerHTML = '';

    // 添加表头
    let thead = document.createElement('thead');
    let headerRow = document.createElement('tr');

    headers.forEach(header => {
      let th = document.createElement('th');
      th.textContent = header;

      // 根据列变化类型添加类
      if (columnChanges[step] && columnChanges[step][header]) {
        const changeType = columnChanges[step][header];
        th.classList.add("col-" + changeType);
      }

      headerRow.appendChild(th);
    });

    thead.appendChild(headerRow);
    table.appendChild(thead);

    // 添加数据行
    let tbody = document.createElement('tbody');

    dataRows.forEach(rowData => {
      let tr = document.createElement('tr');

      rowData.forEach((cellData, index) => {
        let td = document.createElement('td');
        td.textContent = cellData;

        // 为变化列添加样式
        const header = headers[index];
        if (columnChanges[step] && columnChanges[step][header]) {
          const changeType = columnChanges[step][header];
          if (changeType !== "none") {
            td.classList.add("col-" + changeType);
          }
        }

        tr.appendChild(td);
      });

      tbody.appendChild(tr);
    });

    table.appendChild(tbody);

    // 更新列数统计
    document.querySelectorAll('.overview-card')[0].querySelector('.overview-value').textContent = headers.length;
  }

  // 更新数据库表的字段显示
  function updateTableColumns(tableId) {
    const tables = {
      "1": {
        name: "客户信息表",
        columns: [
          {name: "客户ID", type: "用户标识", required: true, dataType: "VARCHAR(20)"},
          {name: "姓名", type: "用户信息", required: true, dataType: "VARCHAR(50)"},
          {name: "省份", type: "地理信息", required: true, dataType: "VARCHAR(20)"},
          {name: "城市", type: "地理信息", required: true, dataType: "VARCHAR(30)"},
          {name: "注册日期", type: "时间信息", required: true, dataType: "DATE"},
          {name: "客户等级", type: "用户属性", required: false, dataType: "VARCHAR(10)"},
          {name: "客户价值", type: "业务指标", required: false, dataType: "DECIMAL(10,2)"},
          {name: "联系方式", type: "联系信息", required: true, dataType: "VARCHAR(50)"}
        ]
      },
      "2": {
        name: "交易记录表",
        columns: [
          {name: "交易ID", type: "交易标识", required: true, dataType: "BIGINT"},
          {name: "客户ID", type: "用户标识", required: true, dataType: "VARCHAR(20)"},
          {name: "产品ID", type: "产品标识", required: true, dataType: "VARCHAR(20)"},
          {name: "交易金额", type: "交易信息", required: true, dataType: "DECIMAL(10,2)"},
          {name: "交易日期", type: "时间信息", required: true, dataType: "DATETIME"},
          {name: "支付方式", type: "交易信息", required: false, dataType: "VARCHAR(20)"}
        ]
      },
      "3": {
        name: "用户行为表",
        columns: [
          {name: "行为ID", type: "行为标识", required: true, dataType: "BIGINT"},
          {name: "客户ID", type: "用户标识", required: true, dataType: "VARCHAR(20)"},
          {name: "行为类型", type: "行为属性", required: true, dataType: "VARCHAR(20)"},
          {name: "行为时间", type: "时间信息", required: true, dataType: "DATETIME"},
          {name: "页面路径", type: "页面信息", required: false, dataType: "VARCHAR(200)"},
          {name: "停留时长", type: "行为指标", required: false, dataType: "INT"}
        ]
      }
    };

    const table = tables[tableId] || tables["1"];
    const tableColumns = table.columns;

    // 更新标题
    document.querySelector('.db-columns-container .db-columns-title .highlight').textContent = table.name;

    // 获取步骤3的列名
    const step3Columns = [
      "customer_id", "full_name", "province", "city",
      "register_date", "loyalty_level", "customer_value"
    ];

    // 计算匹配率
    const matchedColumns = tableColumns.filter(col =>
      step3Columns.includes(col.name.toLowerCase().replace(' ', '_')) ||
      step3Columns.includes(col.name.toLowerCase().replace(' ', ''))
    );
    const matchRate = Math.round((matchedColumns.length / step3Columns.length) * 100);

    // 更新匹配状态
    const matchStatus = document.querySelector('.db-columns-container .match-status');
    matchStatus.textContent = `字段匹配率: ${matchRate}% (${matchedColumns.length}/${step3Columns.length})`;
    if (matchRate === 100) {
      matchStatus.className = "match-status status-match";
    } else {
      matchStatus.className = "match-status status-mismatch";
    }

    // 更新表格
    const tableElement = document.querySelector('.db-columns-table tbody');
    tableElement.innerHTML = '';

    tableColumns.forEach(col => {
      const normalizedName = col.name.toLowerCase().replace(' ', '_');
      const isMatch = step3Columns.includes(normalizedName) ||
        step3Columns.includes(col.name.toLowerCase().replace(' ', ''));
      const row = document.createElement('tr');

      if (isMatch) {
        row.className = "column-match";
      } else {
        row.className = "column-mismatch";
      }

      row.innerHTML = `
        <td>${col.name}</td>
        <td>${col.type}</td>
        <td><i class="fas fa-${col.required ? 'check' : 'times'}-circle" style="color:${col.required ? '#4caf50' : '#f44336'}"></i> ${col.required ? '是' : '否'}</td>
        <td>${col.dataType}</td>
      `;

      tableElement.appendChild(row);
    });
  }

  // 初始化页面
  document.addEventListener('DOMContentLoaded', function() {
    // 初始化树形结构
    initializeTree();

    // 默认选中第一个表
    const firstTableContent = document.querySelector('.db-tree .tree-content');
    if (firstTableContent) {
      firstTableContent.classList.add('selected');
      const tableName = firstTableContent.querySelector('.tree-label').textContent;
      updateFieldComparison(tableName);
    }

    // 初始选择源数据表
    updateDataPreview("1");
  });
</script>
</body>
</html>
